/*
 * Планировщик
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>
#include <limits.h>

#ifdef DEBUG
# define dbg_fprintf(x)	fprintf x
#else
# define dbg_fprintf(x)	((void) 0)
#endif

#define MAX(a, b)	((a) > (b) ? (a) : (b))

/* {{{ memory allocation wrappers */
extern void *s_calloc(size_t n, size_t size)
{
	void *ptr;
	ptr = calloc(n, size);
	assert(ptr != NULL);
	if (ptr == NULL) {
		dbg_fprintf((stderr, "out of memory\n"));
		abort();
	}
	return ptr;
}

extern void *s_malloc(size_t size)
{
	void *ptr;
	ptr = malloc(size);
	assert(ptr != NULL);
	if (ptr == NULL) {
		dbg_fprintf((stderr, "out of memory\n"));
		abort();
	}
	return ptr;
}
/* }}} */

/* {{{ autoarray */
struct vector {
	int *data;
	int n;
	int max;
};
/* {{{ functions */
extern int
vector_init(struct vector *v, int p)
{
	if (v == NULL) {
		fprintf(stderr, "vector_init(): received NULL ptr, not doing anything\n");
		return 1;
	}

	if (p < 0 || p >= (CHAR_BIT * sizeof v->data[0]))
		p = 0;
	v->max = 1 << p;
	v->n = 0;
	v->data = (int *) s_calloc((size_t) v->max, sizeof *v->data);

	return 0;
}

extern int
vector_append(struct vector *v, int a)
{
	int *t = NULL;

	if (v == NULL) {
		fprintf(stderr, "vector_append(): received NULL ptr, not doing anything\n");
		return 1;
	}

	if (v->max == 0)
		vector_init(v, 0);

	if (v->n + 1 > v->max) {
		t = (int *) realloc(v->data, sizeof *t * (v->max *= 2));
		if (!t) {
			fprintf(stderr, "vector_append(): failed to allocate %d bytes\n", v->max);
			return 1;
		} else {
			v->data = t;
		}
	}

	v->data[v->n++] = a;

	return 0;
}

extern int
vector_sort(struct vector *v, int (*cmpf)(const void *, const void *))
{
	if (v == NULL) {
		fprintf(stderr, "vector_sort(): received NULL ptr, not doing anything\n");
		return 1;
	}

	if (v->max > 0 && v->n > 1) {
		qsort(v->data, (size_t) v->n, sizeof *v->data, cmpf);
		return 0;
	} else {
		return 1;
	}
}

extern int
vector_cleanup(struct vector *v)
{
	if (v == NULL) {
		fprintf(stderr, "vector_cleanup(): received NULL ptr, not doing anything\n");
		return 1;
	}

	if (v->max > 0) {
		v->max = v->n = 0;
		free(v->data);
		v->data = NULL;
		return 0;
	} else {
		return 1;
	}
}
/* }}} */
/* }}} */

/* {{{ doubly-linked list */
struct dll_node {
	int x, y;
	struct dll_node *prev, *next;
};
/* {{{ functions */
/*
 * This function inserts one node pointed to by 'ins' _after_ 'node'.
 */
extern struct dll_node *
dll_insert(struct dll_node *node, struct dll_node *ins)
{
	assert(node != NULL);
	if (ins == NULL) {
		dbg_fprintf((stderr, "dll_insert(): ins is NULL, not doing anything\n"));
		return node;
	}

	if (node->next) {
		assert(node->next->prev == node);
		node->next->prev = ins;
	}
	ins->next = node->next;
	ins->prev = node;
	node->next = ins;
	return ins;
}

/*
 * This function extracts 'node' from a doubly-linked list and returns pointer
 * to that node, which pointers '->prev' and '->next' are not reset.
 *
 * If you really want to get rid of a node, call
 * 	free(dll_delete(unneeded_node));
 */
extern struct dll_node *
dll_delete(struct dll_node *node)
{
	if (!node) {
		dbg_fprintf((stderr, "dll_delete(): received NULL ptr, wtf am i supposed to delete?\n"));
		return NULL;
	}

	if (node->prev) {
		assert(node->prev->next == node);
		node->prev->next = node->next;
	}
	if (node->next) {
		assert(node->next->prev == node);
		node->next->prev = node->prev;
	}

	return node;
}

/* }}} */
/* }}} */

/* {{{ graph repr: adjlist w/ doubly-linked list */
enum vertex_st {
	VTX_ST_UNKN = 0,
	VTX_ST_OPEN,
	VTX_ST_VISITED
};

struct adjlist_dll {
	struct dll_node *head;
	struct dll_node *tail;
	size_t _list_len;

	enum vertex_st state;
	int color;
	int distance;
	int parent;
	int fwd, bck; /* dfs tree depth, >=1 unless uninitialized */
	int low; /* lowpoint(), >=1 unless uninitialized */
	int chnum; /* children count for this node */

	int Sec; /* seconds to complete this job */
	int Total; /* max sum of all dependent jobs to complete */
};
/* {{{ functions */
extern void
adjl_dll_connect(struct adjlist_dll *node, const int conid, const int edgeid)
{
	struct dll_node *Wilson;

	Wilson = (struct dll_node *) s_calloc(1, sizeof *Wilson);
	Wilson->x = conid;
	Wilson->y = edgeid;
	Wilson->prev = Wilson->next = NULL;

	if (node->head == NULL) {
		assert(node->tail == NULL);
		node->head = node->tail = Wilson;
		node->_list_len = 1;
	} else {
		node->tail = dll_insert(node->tail, Wilson);
		node->_list_len++;
	}
}

extern void
adjl_dll_cleanup(struct adjlist_dll *al)
{
	struct dll_node *nx = al->head, *pr = al->head;

	while (nx) {
		pr = nx;
		nx = nx->next;
		free(pr);
	}
	al->_list_len = 0;
	al->head = al->tail = NULL;
}
/* }}} */
/* }}} */

int
dfs_main(struct adjlist_dll *al, const int idx, const int anc, int *fwdct)
{
	struct dll_node *nd = al[idx].head;
	int addmax = 0;

	dbg_fprintf((stderr, "%d\tentered node\n",
			idx + 1));

	if (al[idx].state != VTX_ST_UNKN) {
		dbg_fprintf((stderr, "%d\tnode is not VTX_ST_UNKN\n",
				idx + 1));
	}

	al[idx].state = VTX_ST_OPEN;

	while (nd) {
		/* whoops
		if (nd->x == anc)
			goto cont;
		 */

		if (al[nd->x].state == VTX_ST_UNKN) {
			al[nd->x].parent = idx;
			if (dfs_main(al, nd->x, idx, fwdct) == 1)
				return 1;
		} else if (al[nd->x].state == VTX_ST_OPEN) {
			dbg_fprintf((stderr, "%d\tedge (%d, %d): found cycle, bailing out\n",
					idx + 1, idx + 1, nd->x + 1));
			return 1;
		}
		addmax = MAX(addmax, al[nd->x].Total);
cont:
		nd = nd->next;
	}

	al[idx].Total = al[idx].Sec + addmax;
	al[idx].state = VTX_ST_VISITED;

	dbg_fprintf((stderr, "%d\tleaving node\n",
			idx + 1));

	return 0;
}

int
main(int argc, char **argv)
{
	struct adjlist_dll *al;
	int i, n, j;
	int sec, m, x;
	bool extans = true;

	scanf("%d", &n);
	/* al[n] - start, al[n + 1] - finish */
	al = (struct adjlist_dll *) s_calloc(n + 2, sizeof *al);
	for (i = 0; i < n; i++) {
		scanf("%d %d", &sec, &m);
		al[i].Sec = sec;
		for (j = 0; j < m; j++) {
			scanf("%d", &x);
			--x;
			adjl_dll_connect(al + i, x, sec);
		}
	}

	for (i = 0; i < n; i++) {
		if (al[i].state == VTX_ST_UNKN)
			if (dfs_main(al, i, -1, NULL) == 1) {
				dbg_fprintf((stderr, "main(): node %d: dfs found cycle\n",
						i + 1));
				extans = false;
				puts("-1");
				goto cleanup;
			}
	}

	for (sec = i = 0; i < n; i++) {
		if (al[i].Total > sec)
			sec = al[i].Total;
	}
	printf("%d\n", sec);

cleanup:
#ifdef DEBUG
	for (i = 0; i < n; i++) {
		dbg_fprintf((stderr, "al[%d] = { parent=%d, Sec=%d, Total=%d, _list_len=%zu }\n",
				i + 1, al[i].parent, al[i].Sec, al[i].Total,
				al[i]._list_len));
	}
#endif
	for (i = 0; i < n; i++)
		adjl_dll_cleanup(al + i);
	free(al);
	return 0;
}
